package com.bear.fastrepair.mvvm.ui.employee

import android.graphics.Bitmap
import android.net.Uri
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.bear.fastrepair.entity.*
import com.bear.fastrepair.mvvm.data.Result
import com.bear.fastrepair.mvvm.data.employee.EmployeeRepository
import com.bear.fastrepair.utils.*
import com.blankj.utilcode.util.ToastUtils
import okhttp3.ResponseBody
import retrofit2.http.Url
import java.io.File

class EmployeeViewModel(private val repository: EmployeeRepository) : ViewModel() {

    var webSocketStart = false

    /**
     * 获取订单单页数据
     */
    private val _getOrderInfoPage = MutableLiveData<EmployeeOrderInfoPagePosition>()
    val getOrderInfoPage: LiveData<EmployeeOrderInfoPagePosition> = _getOrderInfoPage

    /**
     * 更新工作状态
     */
    private val _updateWorkStatus = MutableLiveData<Int>()
    val updateWorkStatus: LiveData<Int> = _updateWorkStatus

    /**
     * 更新APP
     */
    private val _updateApp = MutableLiveData<AppVersionResponse>()
    val updateApp: LiveData<AppVersionResponse> = _updateApp


    /**
     * 更新APP
     */
    private val _appResponse = MutableLiveData<ResponseBody>()
    val appResponse: LiveData<ResponseBody> = _appResponse


    private val _filterOrderStatus = MutableLiveData<ArrayList<Int>>().apply { value = ArrayList() }
    val filterOrderStatus: LiveData<ArrayList<Int>> = _filterOrderStatus

    /**
     * 获取订单详情
     */
    private val _getOrderInfo = MutableLiveData<OrderInfoDetail>()
    val getOrderInfoDetail: LiveData<OrderInfoDetail> = _getOrderInfo

    /**
     * 获取订单详情
     */
    private val _saveBookingTime = MutableLiveData<ResponseInfo>()
    val saveBookingTime: LiveData<ResponseInfo> = _saveBookingTime

    /**
     * 上传图片（账单）
     */
    private val _imageUploadBill = MutableLiveData<ResponseListInfo>()
    val imageUploadBill: LiveData<ResponseListInfo> = _imageUploadBill

    /**
     * 员工获取个人信息
     */
    private val _personalInfo = MutableLiveData<EmployeeInfo2>()
    val personalInfo: LiveData<EmployeeInfo2> = _personalInfo

    /**
     * 打卡状态
     */
    private val _clockIn = MutableLiveData<Int>()
    val clockIn: LiveData<Int> = _clockIn

    /**
     * 订单状态
     */
    private val _serviceOrderStatus = MutableLiveData<Int?>()
    var serviceOrderStatus: LiveData<Int?> = _serviceOrderStatus

    /**
     * 已选图片
     */
    private val _selectedImage = MutableLiveData<List<Uri>>()
    val selectedImage: LiveData<List<Uri>> = _selectedImage

    val billInfo = MutableLiveData<BillInfoAdd>()

    private val _captureImage = MutableLiveData<Bitmap>()
    val captureImage: LiveData<Bitmap> = _captureImage

    /**
     * 账单详情
     */
    private val _billDetail = MutableLiveData<BillInfoResponse>()
    val billDetail: LiveData<BillInfoResponse> = _billDetail

    private val _orderImages = MutableLiveData<OrderImagesResponse>()
    val orderImages: LiveData<OrderImagesResponse> = _orderImages

    private val _orderImageUpload = MutableLiveData<OrderImageUpload>()
    val orderImageUpload: LiveData<OrderImageUpload> = _orderImageUpload

    private val _resetPassword = MutableLiveData<ResponseInfo>()
    val resetPassword: LiveData<ResponseInfo> = _resetPassword

    val bookingTime = MutableLiveData<Array<String>?>()


    fun getOrderInfoPage(
        current: Int,
        size: Int,
        orderStatus: Int? = null,
        loadMore: Boolean = false
    ) = launch {
        when (val result = repository.getOrderInfoPage(current, size, orderStatus)) {
            is Result.Success -> _getOrderInfoPage.value =
                EmployeeOrderInfoPagePosition(result.data, current, loadMore)
            is Result.Error -> _getOrderInfoPage.value =
                EmployeeOrderInfoPagePosition(result.data!!, current, loadMore)
        }
    }

    fun updateWorkStatus(workStatus: EmployeeWorkStatus) = launch {
        when (val result = repository.updateWorkStatus(workStatus)) {
            is Result.Success -> {
                getPersonalInfo()
                SharedPreferencesHelper.putInfo(WORK_STATUS_KEY, workStatus.workStatus)
                _updateWorkStatus.value = workStatus.workStatus
            }
            is Result.Error -> _updateWorkStatus.value = workStatus.workStatus
        }
    }

    fun updateLocation(location: UpdateLocation) = launch {
        when (val result = repository.updateLocation(location)) {
            is Result.Success -> {
                getPersonalInfo()
                ToastUtils.showLong("更新位置信息成功")
            }
            is Result.Error -> {
                ToastUtils.showLong("更新位置信息失败，请检查网络和定位权限")
            }
        }
    }

    fun updateApp() = launch {
        when(val result = repository.updateApp()) {
            is Result.Success -> {
                _updateApp.value = result.data
            }
            is Result.Error -> {
                _updateApp.value = result.data!!
            }
        }
    }

    fun downloadApp(@Url fileUrl: String) = launch {
        when(val result = repository.downloadApp(fileUrl)) {
            is Result.Success -> {
                _appResponse.value = result.data
            }
            is Result.Error -> {
                _appResponse.value = result.data!!
            }
        }
    }

    fun resetPassword(resetPasswordBean: ResetPasswordBean) = launch {
        when (val result = repository.resetPassword(resetPasswordBean)) {
            is Result.Success -> {
                _resetPassword.value = result.data
            }
            is Result.Error -> {
                _resetPassword.value = result.data!!
            }
        }
    }

    fun getOrderById(id: String) = launch {
        when (val result = repository.getOrderById(id)) {
            is Result.Success -> _getOrderInfo.value = result.data
            is Result.Error -> _getOrderInfo.value = result.data!!
        }
    }

    fun saveBookingTime(serviceOrderId: String, bookingBody: BookingBody) = launch {
        when (val result = repository.saveBookingTime(serviceOrderId, bookingBody)) {
            is Result.Success -> {
                _saveBookingTime.value = result.data
            }
            is Result.Error -> {
                ToastUtils.showLong("预约时间设置失败，请重试")
                _saveBookingTime.value = result.data!!
            }
        }
    }

    fun imageUpload(path: String = "mobile", params: List<File>) = launch {
        when (val result = repository.imageUpload(path, params)) {
            is Result.Success -> _imageUploadBill.value = result.data
            is Result.Error -> _imageUploadBill.value = result.data!!
        }
    }

    fun imageUploadOrder(path: String = "mobile", params: List<File>, status: Int, remark: String) =
        launch {
            when (val result = repository.imageUpload(path, params)) {
                is Result.Success -> _orderImageUpload.value =
                    OrderImageUpload(result.data, status, remark)
                is Result.Error -> _orderImageUpload.value =
                    OrderImageUpload(result.data!!, status, remark)
            }
        }

    fun employeeClockIn(
        locationAddress: String,
        locationLatitude: String,
        locationLongitude: String,
        serviceOrderId: String?,
        adapterItemId: Int = -1
    ) = launch {
        when (val result = repository.employeeClockIn(
            locationAddress,
            locationLatitude,
            locationLongitude,
            serviceOrderId
        )) {
            is Result.Success -> {
                serviceOrderId?.let { getOrderById(it) }
                ToastUtils.showLong("打卡成功")
                _clockIn.value = adapterItemId
                orderStatusUpdate(CLOCK_IN)
            }
            is Result.Error -> {
                ToastUtils.showLong("打卡失败，${result.data?.msg}")
                _clockIn.value = adapterItemId
            }
        }
    }

    fun takeMachineBackRepaired(
        serviceOrderId: String,
        images: String? = null,
        remark: String? = null
    ) = launch {
        when (val result = repository.takeMachineBackRepaired(serviceOrderId, images, remark)) {
            is Result.Success -> {
                getOrderById(serviceOrderId)
                ToastUtils.showLong("带回机器维修完成")
                orderStatusUpdate(TAKE_BACK_REPAIRED)
            }
            is Result.Error -> {
                ToastUtils.showLong("设置带回机器维修异常，${result.data?.msg}")
            }
        }
    }

    fun orderComplete(
        serviceOrderId: String,
        images: String? = null,
        remark: String? = null
    ) = launch {
        when (val result = repository.orderComplete(serviceOrderId, images, remark)) {
            is Result.Success -> {
                getOrderById(serviceOrderId)
                ToastUtils.showLong("完成订单")
                orderStatusUpdate(ORDER_COMPLETE)
            }
            is Result.Error -> {
                ToastUtils.showLong("设置完成订单异常，${result.data?.msg}")
            }
        }
    }

    fun orderBack(
        serviceOrderId: String,
        images: String? = null,
        remark: String? = null
    ) = launch {
        when (val result = repository.orderBack(serviceOrderId, images, remark)) {
            is Result.Success -> {
                getOrderById(serviceOrderId)
                ToastUtils.showLong("退回订单")
                orderStatusUpdate(ORDER_SEND_BACK)
            }
            is Result.Error -> {
                ToastUtils.showLong("设置退回订单异常，${result.data?.msg}")
            }
        }
    }

    fun takeMachineBack(
        serviceOrderId: String,
        images: String? = null,
        remark: String? = null
    ) = launch {
        when (val result = repository.takeMachineBack(serviceOrderId, images, remark)) {
            is Result.Success -> {
                getOrderById(serviceOrderId)
                ToastUtils.showLong("带回机器")
                orderStatusUpdate(MACHINE_TAKE_BACK)
            }
            is Result.Error -> {
                ToastUtils.showLong("设置带回机器异常，${result.data?.msg}")
            }
        }
    }

    fun addOrderBill(billInfoAdd: BillInfoAdd) = launch {
        when (val result = repository.addOrderBill(billInfoAdd)) {
            is Result.Success -> {
                ToastUtils.showLong("添加订单完成")
            }
            is Result.Error -> {
                ToastUtils.showLong("添加订单失败，${result.data?.msg}")
            }
        }
        addImages(emptyList())
    }

    fun getBillInfoById(id: String) = launch {
        when (val result = repository.getBillInfoById(id)) {
            is Result.Success -> _billDetail.value = result.data
            is Result.Error -> _billDetail.value = result.data!!
        }
    }

    fun getImagesById(id: String) = launch {
        when (val result = repository.getImagesById(id)) {
            is Result.Success -> _orderImages.value = result.data
            is Result.Error -> _orderImages.value = result.data!!
        }
    }

    fun uploadImages(image: EmployeeUploadImage) = launch {
        when (val result = repository.uploadImages(image)) {
            is Result.Success -> {
                ToastUtils.showLong("图片项目上传成功")
                getOrderById(image.serviceOrderId)
            }
            is Result.Error -> ToastUtils.showLong("图片上传失败，${result.data?.msg}")
        }
    }

    fun getPersonalInfo() = launch {
        when (val result = repository.getPersonalInfo()) {
            is Result.Success -> _personalInfo.value = result.data
            is Result.Error -> _personalInfo.value = result.data!!
        }
    }

    fun updateFilterOrderStatus(orderStatus: Int, status: Boolean) {
        if (status && _filterOrderStatus.value?.contains(orderStatus) != true) {
            _filterOrderStatus.value?.add(orderStatus)
        } else {
            _filterOrderStatus.value?.remove(orderStatus)
        }
        getOrderInfoPage(1, 100)
    }

    fun orderStatusUpdate(status: Int?) {
        _serviceOrderStatus.value = status
    }

    fun addImages(list: List<Uri>) {
        _selectedImage.value = list
    }

    fun addBitmap(bitmap: Bitmap) {
        _captureImage.value = bitmap
    }

    fun updateBookingTime(times: Array<String>) {
        bookingTime.value = times
    }
}